# -*- coding: utf-8 -*-
#!/usr/bin/env python

import os
import datetime

if os.name == 'nt':
    FolderExistsError = (WindowsError, OSError)
    FolderExistsCode = (183, 17)
elif os.name == 'posix':
    FolderExistsError = (OSError,)
    FolderExistsCode = (17,)

_codec_list = []
def _get_codec_list():
    global _codec_list
    if not _codec_list:
        import encodings
        filePath = getattr(encodings, '__file__')
        folder = os.path.dirname(filePath)
        files = os.listdir(folder)
        fileNameExcept = ('.', '..', '__init__', 'aliases', 'base64_codec', 
                          'bz2_codec', 'charmap', 'hex_codec', 'idna', 
                          'punycode', 'quopri_codec', 'rot_13', 
                          'string_escape', 'undefined', 'uu_codec', 
                          'zlib_codec', 'unicode_escape', 'unicode_internal')
        extExcept = ('.pyc', '.pyo')
        _codec_list = ['ascii', 'gbk', 'gb2312', 'big5', 'mbcs', 'utf_8']
        for eachFile in files:
            fileName, ext = os.path.splitext(eachFile)
            if not (ext in extExcept or fileName in fileNameExcept or fileName in _codec_list):
                    _codec_list.append(fileName)

def trydecode(inputStr):
    global _codec_list
    if inputStr == None:
        return inputStr, 0
    if isinstance(inputStr, unicode):
        return inputStr, 0
    try:
        return inputStr.decode('ascii'), 0
    except:
        pass
    _get_codec_list()
    for eachCodec in _codec_list:
        try:
            ds = inputStr.decode(eachCodec)
            if inputStr == ds.encode(eachCodec):
                return ds, 0
        except:
            pass
    return inputStr, -1

def tryencode(inputStr):
    global _codec_list
    if inputStr == None:
        return inputStr
    if isinstance(inputStr, str):
        return inputStr
    try:
        return inputStr.encode("ascii")
    except:
        pass    
    _get_codec_list()
    for eachCodec in _codec_list:
        try:
            es = inputStr.encode(eachCodec)
            if inputStr == es.decode(eachCodec):
                return es
        except:
            pass
    return inputStr

def dt_timedelta_month(dt, cnt_month):
    """获得上一个月"""
    dt_month = dt.year * 12 + dt.month   
    if (cnt_month >= 0 and cnt_month<= dt_month) or (cnt_month < 0 and abs(cnt_month) + dt_month <= 9999 * 12):
        dt_month += cnt_month
        y, m = divmod(dt_month, 12)
        if m == 0:
            y -= 1
            m = 12
    dt = datetime.datetime(y,m,dt.day, dt.hour, dt.minute, dt.second)
    return dt

def ensure_unicode(val):
    """确保val是unicode"""
    codec_list = ['ascii', 'utf-8', 'gbk', 'gb2312', 'big5']
    if val is None:
        return u''
    if not isinstance(val, str) and not isinstance(val, unicode):
        val = unicode(val)
    if isinstance(val, unicode):
        return val
    if isinstance(val, str):
        val = ''.join(filter(lambda c:c != '\0', val)) #去掉NUL
    for c in codec_list:
        try:
            ds = val.decode(c)
            return ds
        except:
            pass
    return u''

if __name__ == '__main__':
#    aa = datetime.datetime(2007,5,1)
#    print dt_timedelta_month(aa, 1).strftime('%Y-%m-%d')
#    print dt_timedelta_month(datetime.datetime(2007,5,1),-1).strftime('%Y-%m-%d')
#    print dt_timedelta_month(datetime.datetime(2007,5,1),1).strftime('%Y-%m-%d')

#    str = u'但是fds'
#    str,ret = trydecode(str)
#    print str,ret
    
    print ensure_unicode('fds犯得上')
    
